#pragma once
#include<iostream>
#include <fstream>
#include<sstream>
#include<vector>
#include"Socket.hpp"
#include "log.hpp"

//#include<pthread.h>
extern Log lg;
const std::string wwwroot="./wwwroot";//web根目录
const std::string homepage="index.html";//首页
const std::string newline_sep="\r\n";//换行分隔符
struct ThreadData
{
    int sock_fd;
};
class HttpRequest
{
    public:
    bool Deserialize(std::string buffer)
    {
        //"method url httpversion\r\n"
        while(true)
        {
       size_t pos= buffer.find(newline_sep);
       if(pos==std::string::npos)return false;
       std::string line=buffer.substr(0,pos);
        buffer.erase(0,pos+2);//\r\n也要删掉
       if(line.empty())break;
        response_header.push_back(line);
        }
        text_=buffer;
        return true;
    }
    void Parsing()
    {
        std::stringstream ss(response_header[0]);
        ss>>method>>url>>http_version;
        path=wwwroot;//./wwwroot
        if(url=="/"||url=="/index.html")
        {
        path+="/";
        path+=homepage;
        }
        else // /a/b/c/d/index.html
        path+=url;
    }
    void Debug()
    {
        for(auto &line:response_header)
        {
            std::cout<<"---------------------"<<std::endl;
            std::cout<<line<<std::endl;
        }
        std::cout<<"method: "<<method<<std::endl;
        std::cout<<"url: "<<url<<std::endl;
        std::cout<<"http_version: "<<http_version<<std::endl;
        std::cout<<"path: "<<path<<std::endl;

    }
   public:
    std::vector<std::string> response_header;
    std::string text_;//请求正文

    //解析后的结果
    std::string method;
    std::string url; 
    std::string http_version;
    std::string path; //网页文件路径
};
class HttpServer
{
    public:
    HttpServer(const uint16_t&port)
    :port_(port)
    {

    }
    void Start()
    {
        listen_fd.Socket();
        listen_fd.Bind(port_);
        listen_fd.Linsten();
        lg(INFO,"Init sucess!!");
        while(true)
        {
            uint16_t clientport;
            std::string clientip;
            int newfd=listen_fd.Accept(&clientport,&clientip);
            if(newfd==-1)continue;
            lg(INFO,"Server get a new link , sockfd is:%d",newfd);
            ThreadData*td=new ThreadData();
            td->sock_fd=newfd;
            pthread_t pid;
            pthread_create(&pid,nullptr,ThreadRun,td);

        }
    }
    static std::string ReadHtmlContent(const std::string&htmlpath)
    {
        std::ifstream in(htmlpath);
        if(!in.is_open())return "404";
        std::string res;
        std::string line;
        while(getline(in,line))
        {
            res+=line;
        }
        return res;
    }
    static void HandlerHttp(int sockfd)
    {
        char buffer[10240];
       ssize_t n= recv(sockfd,buffer,sizeof(buffer)-1,0);
       if(n>0)
       {
            buffer[n]=0;
            std::cout<<buffer<<std::endl;
       }
       //响应请求
        HttpRequest rq;
        rq.Deserialize(buffer);
        rq.Parsing();
        rq.Debug();


      
       std::string response_body=ReadHtmlContent(rq.path);//响应正文
        std::string response_line="HTTP/1.1 200 ok\r\n";//状态行
        std::string response_header="Conten_Length:";//响应报头
        response_header+=std::to_string(response_body.size());
        std::string response=response_line;
        response+=response_header;
        response+=newline_sep;
        response+=newline_sep;//空行
        response+=response_body;
        send(sockfd,response.c_str(),response.size(),0);
        close(sockfd);
    }
    static void* ThreadRun(void*args)
    {
        pthread_detach(pthread_self());
        ThreadData*td=static_cast<ThreadData*>(args);
        HandlerHttp(td->sock_fd);
        delete td;
        return nullptr;
    }
    ~HttpServer()
    {

    }
    private:
    Sock listen_fd;
    uint16_t port_;
};